package com.yxt.ui;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
import com.yxt.common.sys.CommConstant;
import com.yxt.common.sys.CommUtil;
import com.yxt.common.sys.StringUtil;
import com.yxt.common.ui.ActivityStackControlUtil;
import com.yxt.common.ui.StationOverlay;
import com.yxt.exception.InternetException;
import com.yxt.exception.RemoteServerException;
import com.yxt.exception.XmlParserException;

import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.Html;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class TyphoonTrackActivity extends MapActivity {
	private static final int MODEL_SATELITE = Menu.FIRST + 1;
	private static final int MODEL_STREET = Menu.FIRST + 2;
	private static final int TYPHOON_LIST = Menu.FIRST + 3;
	private static final int TYPHOON_TRACK = Menu.FIRST + 4;
	
	private List<Map<String, String>> typhoons = new ArrayList<Map<String, String>>();
	private Map<String, List<Map<String, String>>> trackmap = new HashMap<String, List<Map<String, String>>>();
	private Map<String, List<Map<String, String>>> forecastmap = new HashMap<String, List<Map<String, String>>>();
	private MapView mapView;
	private String code;
	private ProgressDialog dialog;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏
		setContentView(R.layout.typhoon_track); // 软件activity的布局
		ActivityStackControlUtil.add(this);
		Button btnBackHome = (Button) findViewById(R.id.btnBackHome);
		btnBackHome.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				Intent intent = new Intent();
				intent.setClass(getApplicationContext(), MainActivity.class);
				startActivity(intent);
			}
		});
		mapView = (MapView) findViewById(R.id.map_view);
		initComponent();
	}
	
	private void downloadTyphoonTrack() {
		try {
			InputStream inputStream = getInputStream();
			SAXParserFactory factory = SAXParserFactory.newInstance();
			SAXParser parser = factory.newSAXParser();
			parser.parse(inputStream, new TrackHandler());
		} catch (IOException e) {
			dialog.cancel();
			throw new InternetException("");
		} catch (ParserConfigurationException e){
			dialog.cancel();
			throw new XmlParserException("");
		} catch(SAXException ex) {
			dialog.cancel();
			throw new XmlParserException("");
		}
	}

	private InputStream getInputStream() throws IOException {
		Intent intent = getIntent();
		String server = "";
		String tfcode = "";
		if ("".equals(CommConstant.Sever.TFDATA_SERVER)) {
			String itemId = intent.getStringExtra("itemId");
			Map<String, String> menu = CommConstant.Main.FUNCTIONS.get(CommConstant.Main.CURRENT_TEMPLATE_CODE).get(itemId);
			server = menu.get("server");
			CommConstant.Sever.TFDATA_SERVER = server;
		}else {
			server = CommConstant.Sever.TFDATA_SERVER;
			tfcode = intent.getStringExtra("tfcode");
			if (tfcode == null)
				tfcode = "";
		}
		InputStream input = null;
		if (CommConstant.DEBUG_MODEL) {
			input = new FileInputStream(CommConstant.Config.DEFAULT_PHONE_DIR + CommConstant.Config.XML_LOCATION +"tftrack.xml");
		} else {
			URL url = new URL(server+ "tfdata/TFDetail.aspx?iphoneid=" + CommConstant.Main.CURRENT_IPHONE_CODE + "&version=" + CommConstant.Main.CURRENT_IPHONE_VERSION + "&areacode=" + CommConstant.Main.CURRENT_AREA_CODE + "&rvnm="+CommConstant.Main.CURRENT_RIVER_CODE+"&tfcode="+tfcode+"&ename=");
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(CommConstant.Config.DEFAULT_TIMEOUT);
			conn.connect();
			input = conn.getInputStream();
		}
		return input;
	}

	private class TrackHandler extends DefaultHandler {
		public void startElement(String uri, String localName, String qName,
				Attributes attrs) throws SAXException {
			if (localName.startsWith("tfinfo")) {
				code = attrs.getValue("code");
				Map<String, String> data = new HashMap<String, String>();
				for (int i = 0; i < attrs.getLength(); i++) {
					data.put(attrs.getLocalName(i), attrs.getValue(i));
				}
				typhoons.add(data);
			} else if (localName.startsWith("trackpos")) {
				Map<String, String> data = new HashMap<String, String>();
				for (int i = 0; i < attrs.getLength(); i++) {
					data.put(attrs.getLocalName(i), attrs.getValue(i));
				}
				if (trackmap.containsKey(code)) {
					trackmap.get(code).add(data);
				} else {
					List<Map<String, String>> list = new ArrayList<Map<String, String>>();
					list.add(data);
					trackmap.put(code, list);
				}
			} else if (localName.startsWith("forecastpos")) {
				Map<String, String> data = new HashMap<String, String>();
				for (int i = 0; i < attrs.getLength(); i++) {
					data.put(attrs.getLocalName(i), attrs.getValue(i));
				}
				if (forecastmap.containsKey(code)) {
					forecastmap.get(code).add(data);
				} else {
					List<Map<String, String>> list = new ArrayList<Map<String, String>>();
					list.add(data);
					forecastmap.put(code, list);
				}
			} else if ("message".equals(localName)) {
				dialog.cancel();
				throw new RemoteServerException(attrs.getValue("info"));
			}
		}
	}
	
	private void initComponent() {
		dialog = new ProgressDialog(this);
		dialog.setTitle("提示");
		dialog.setMessage("数据下载中,请稍候...");
		dialog.show();
		final Handler hanlder = new Handler(){
			// 处理来自线程的消息,并将线程中的数据设置入listview
			public void handleMessage(Message msg)	{
				if (msg.what == 1)	{
					int tywd = 0;
					int tyjd = 0;
					//当前台风,下面显示
					StringBuffer buffer = new StringBuffer();
					//当前台风,标题
					StringBuffer title = new StringBuffer();
					//台风集合
					int size = typhoons.size();
					for (int i = 0; i < size; i++) {
						List<GeoPoint> points = new ArrayList<GeoPoint>();
						Map<String, String> typhoon = typhoons.get(i);
						String code = typhoon.get("code");
						String name = typhoon.get("name");
						buffer.append("<font color=\"#FFFFFF\">台风：</font>");
						buffer.append("<font color=\"#FF8000\">" + name + "</font>&nbsp;&nbsp;&nbsp;&nbsp;");
						buffer.append("<font color=\"#FFFFFF\">编号：</font>");
						buffer.append("<font color=\"#FF8000\">" + code + "</font>&nbsp;&nbsp;&nbsp;&nbsp;");
						if (i > 0) {
							title.append(",");
						}
						title.append(name);
						
						List<Map<String, String>> tracks = trackmap.get(code);
						int tracksize = tracks.size();
						for (int j = 0; j < tracksize; j++) {
							Map<String, String> data = tracks.get(j);
							int jd = CommUtil.getGisDegree(data.get("jd"));
							int wd = CommUtil.getGisDegree(data.get("wd"));
							if (i == 0 && j == 0) {
								tywd = wd;
								tyjd = jd;
							}
							GeoPoint point = new GeoPoint(wd, jd);
							points.add(point);
							if (j == tracksize - 1) {
								StringBuffer tpmsg = new StringBuffer();
								tpmsg.append(name + "("+ code + " " + typhoon.get("ename") +")");
								tpmsg.append("\n");
								tpmsg.append("时间" + data.get("time") + "\n风力" + data.get("ydsd") + "级\n气压" + data.get("zxqy")+"hPa");
								StationOverlay overlay = new StationOverlay(getApplicationContext(),point, tpmsg.toString());
								mapView.getOverlays().add(overlay);
							}
						}
						List<Map<String, String>> forecasts = forecastmap.get(code);		
						//添加坐标圆圈
						TyphoonOverlay overlay = new TyphoonOverlay(tracks, forecasts);
						mapView.getOverlays().add(overlay);
						//添加路径曲线
						Polyline polyline = new Polyline(points);
						mapView.getOverlays().add(polyline); // map是MapView类型
						mapView.invalidate();
					}
					//添加预警线
					addForecastLine(CommConstant.Typhoon.POINTS1,CommConstant.Typhoon.MARK24);
					addForecastLine(CommConstant.Typhoon.POINTS2,CommConstant.Typhoon.MARK48);
					//如果存在当前台风,则定位到第一个台见坐标
					if (size > 0) {
						MapController mc = mapView.getController();
						mc.setZoom(CommConstant.Config.DEFAULT_ZOOM);
						mc.animateTo(new GeoPoint(tywd, tyjd));
					} else {
						MapController mc = mapView.getController();
						mc.setZoom(CommConstant.Config.DEFAULT_ZOOM);
						mc.animateTo(new GeoPoint(CommUtil.getGisDegree(CommConstant.Typhoon.DEFAULT_LOCATION[0][0]), CommUtil.getGisDegree(CommConstant.Typhoon.DEFAULT_LOCATION[0][1])));
					}
					
					TextView lblTyphoonList = (TextView) findViewById(R.id.lblTyphoonList);
					lblTyphoonList.setText(Html.fromHtml(buffer.toString()));
					
					TextView lblTitle = (TextView) findViewById(R.id.lblTitle);
					lblTitle.setText(title.toString());		
					dialog.cancel();
				}
			}
		};
		
		new Thread(){
			public void run(){
				Looper.prepare();
				downloadTyphoonTrack();
				Message m = new Message();
				m.what = 1;
				hanlder.sendMessage(m);	// 给handle发送的消息
				Looper.loop();
			};

		}.start();
	}
	
	private void addForecastLine(float[][] array,String type){
		List<GeoPoint> points = new ArrayList<GeoPoint>();
		for (int i = 0; i < array.length; i++) {
			float wd = array[i][0];
			float jd = array[i][1];
			points.add(new GeoPoint(CommUtil.getGisDegree(wd),CommUtil.getGisDegree(jd)));
		}
		Polyline polyline = new Polyline(points,type);
		mapView.getOverlays().add(polyline); // map是MapView类型
	}


	/**
	 * 创建底部菜单
	 * */
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, TYPHOON_LIST, 1, R.string.menu_typhoonlist);
		menu.add(0, TYPHOON_TRACK, 2, R.string.menu_typhoontrack);
		menu.add(0, MODEL_SATELITE, 3, R.string.model_satelite);
		menu.add(0, MODEL_STREET, 4, R.string.model_street);
		return super.onCreateOptionsMenu(menu);
	}

	/**
	 * 点击底部菜单项时的处理
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent = new Intent();
		switch (item.getItemId()) {
			case TYPHOON_LIST:
				intent.setClass(getApplicationContext(), TyphoonListActivity.class);
				startActivity(intent);
				return true;
			case TYPHOON_TRACK:
				if (typhoons.size() == 0) {
					Toast.makeText(TyphoonTrackActivity.this, "当前台风为空,无法查看路径信息", Toast.LENGTH_LONG).show();
				} else {
					Map<String, String> data = typhoons.get(0);
					intent.setClass(getApplicationContext(),TyphoonDataActivity.class);
					intent.putExtra("code", data.get("code"));
					intent.putExtra("ename", data.get("ename"));
					startActivity(intent);
				}
				return true;
			case MODEL_SATELITE:
				mapView.setSatellite(true);
				mapView.setStreetView(false);
				return true;
			case MODEL_STREET:
				mapView.setStreetView(true);
				mapView.setSatellite(false);		
				return true;
			}
			return super.onOptionsItemSelected(item);
	}

	protected boolean isRouteDisplayed() {
		return false;
	}

	class Polyline extends Overlay {
		private List<GeoPoint> points;
		private String style;

		public Polyline(List<GeoPoint> points) {
			this(points,null);
		}
		
		public Polyline(List<GeoPoint> points,String style) {
			this.points = points;
			this.style = style;
		}

		public boolean draw(Canvas canvas, MapView mapView, boolean shadow,long when) {
			draw(canvas, mapView, shadow);
			return false;
		}

		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			if (!shadow) {// 不是绘制shadow层
				Projection projection = mapView.getProjection();
				if (points.size() >= 2) {
					Paint paint = new Paint();
					paint.setAlpha(150);
					paint.setAntiAlias(true);
					if (StringUtil.isEmpty(style)) {
						paint.setStyle(Paint.Style.FILL_AND_STROKE);
						paint.setColor(Color.BLACK);
						paint.setStrokeWidth(1);
						Point start = new Point();//获取第一点的坐标
						projection.toPixels(points.get(0), start);// 需要转换坐标
						for (int i = 1; i < points.size(); i++) {
							Point end = new Point();
							projection.toPixels(points.get(i), end);
							canvas.drawLine(start.x, start.y, end.x, end.y,paint);// 绘制到canvas上即可
							start = end;
						}
					} else {
						paint.setStyle(Paint.Style.STROKE);
						if (CommConstant.Typhoon.MARK24.equals(style)) {
							paint.setColor(CommConstant.Typhoon.COLOR24);
						} else {
							paint.setColor(CommConstant.Typhoon.COLOR48);
						}
						paint.setStrokeWidth(2);
						Point start = new Point();//获取第一点的坐标
						PathEffect effects = new DashPathEffect(new float[] { 20, 20, 20, 20 }, 1); 
						paint.setPathEffect(effects);
						projection.toPixels(points.get(0), start);// 需要转换坐标
						Path path = new Path(); 
						for (int i = 1; i < points.size(); i++) {
							path.moveTo(start.x, start.y);
							Point end = new Point();
							projection.toPixels(points.get(i), end);
							path.lineTo(end.x, end.y);
							canvas.drawPath(path, paint); 
							start = end;
						}
					}
				}
			}
		}
	}

	class TyphoonOverlay extends Overlay {
		final static int picWidth = 20;// 气球图的宽度
		final static int picHeight = 34;// 气球图的高度
		final static int arcR = 8;// 信息窗口的圆角半径
		private List<Map<String, String>> tracks = new ArrayList<Map<String, String>>();

		public TyphoonOverlay(List<Map<String, String>> tracks,List<Map<String, String>> forecasts) {
			this.tracks = tracks;
		}

		// 绘制自定义Overlay的方法
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			int size = tracks.size();
			for (int i = 0; i < size; i++) {
				Map<String, String> data = tracks.get(i);
				Paint paint = getPaint(data.get("zxfs"));
				int wd = CommUtil.getGisDegree(data.get("wd"));
				int jd = CommUtil.getGisDegree(data.get("jd"));
				GeoPoint geo = new GeoPoint(wd, jd);
				Point point = getPoint(mapView, geo);
				canvas.drawCircle(point.x, point.y,
						CommConstant.Typhoon.TYPHOON_RADIUS, paint);
				if (i == size - 1) {
					int radius7 = "".equals(data.get("radius7")) ? 0 : Integer.parseInt(data.get("radius7"));
					int radius10 = "".equals(data.get("radius10")) ? 0 : Integer.parseInt(data.get("radius10"));
					if (radius7 > 0) {
						int r1 = (int) ((radius7 / 110.94) * 1E6);
						GeoPoint g2 = new GeoPoint(wd, jd + r1);
						Point p2 = getPoint(mapView, g2);
						float radius = (p2.x - point.x) * 100 / 400;
						Paint pt2 = new Paint();
						pt2.setColor(Color.argb(1, 128, 128, 255));
						pt2.setAlpha(150);
						pt2.setAntiAlias(true);
						pt2.setStyle(Paint.Style.FILL_AND_STROKE);
						pt2.setStrokeWidth(1);
						canvas.drawCircle(point.x, point.y, radius, pt2);
					}
					if (radius10 > 0) {
						int r1 = (int) ((radius10 / 110.94) * 1E6);
						GeoPoint g2 = new GeoPoint(wd, jd + r1);
						Point p2 = getPoint(mapView, g2);
						float radius = (p2.x - point.x) * 100 / 400;
						Paint pt2 = new Paint();
						pt2.setColor(Color.argb(1, 255, 128, 128));
						pt2.setAlpha(150);
						pt2.setAntiAlias(true);
						pt2.setStyle(Paint.Style.FILL_AND_STROKE);
						pt2.setStrokeWidth(1);
						canvas.drawCircle(point.x, point.y, radius, pt2);
					}
				}
			}
			super.draw(canvas, mapView, false);// 调用父类绘制
		}

		public Paint getPaint(String fs) {
			Paint paint = new Paint();
			paint.setColor(CommUtil.getColor(fs));
			paint.setAlpha(150);
			paint.setAntiAlias(true);
			paint.setStyle(Paint.Style.FILL_AND_STROKE);
			paint.setStrokeWidth(1);
			return paint;
		}

		// 将经纬度翻译此屏幕上XY坐标的方法
		public Point getPoint(MapView mapView, GeoPoint geop) {
			// 将经纬度翻译成屏幕上的XY坐标
			Projection projection = mapView.getProjection();
			Point point = new Point();// 创建用于存储XY坐标的point对象
			projection.toPixels(geop, point);// 调用toPoint方法进行换算
			return point;// 返回结果
		}
	}

	protected void onDestroy() {
		super.onDestroy();
        ActivityStackControlUtil.remove(this);
	}
}